/**
 * 
 */
package gisc.gov.vn.dev.dataManager;

import gisc.gov.vn.dev.util.EGiscType;
import gisc.gov.vn.dev.util.GiscConverter;
import gisc.gov.vn.dev.util.IGiscConverter;

import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.cresques.io.data.IQueryableRaster;

/**
 * @author HT
 *
 */
public class GiscQueryFilterBuilder {
	

	private String user="postgres";
	private String db="database";
	private String pass="postgres";
	private String table="";
	private List<String> fields = new ArrayList<String>();
	private List<String> values=new ArrayList<String>();
	private List<String> table4Grant= new ArrayList<String>();
	private ArrayList<String> arrUserInfo = new ArrayList<String>();
	//private Map<String, String> values = new HashMap<String, String>();
	private String sql;
	private String driver="org.postgresql.Driver";
	private int resultType = ResultSet.TYPE_SCROLL_INSENSITIVE;
	private int resultConcurency = ResultSet.CONCUR_UPDATABLE;
	private EGiscModeQuery mode=EGiscModeQuery.SELECT;
	private EGiscTypeQuery typeQuery = EGiscTypeQuery.NEW;
	private EGiscGrant typeGrant = EGiscGrant.SELECT;
	private IGiscConverter convert=new GiscConverter();
	
	public GiscQueryFilterBuilder(){}
	
	/**
	 * Dùng để build câu lệnh SQL theo các tham số
	 * @author HT
	 * @return
	 */
	public IGiscQueryFilter BuildQuery()
	{
		switch (this.mode) {
		case SELECT:
			this.sql="";
			break;
		case INSERT:
			this.sql="INSERT INTO "+this.table+"("+convert.ListToStringWithCommas(fields) +") ";
			this.sql+="VALUES ("+convert.ListToStringWithCommas(values)+");";
			break;
		case CREATEROLE:
			this.sql="CREATE ROLE "+this.user+" LOGIN  ENCRYPTED PASSWORD '"+this.pass+"'"+"  NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE ;";
			break;
		case GRANT:
			sql="";
			int len=table4Grant.size();
			for(int i=0; i<len; i++)
			{
				sql+="GRANT "+this.typeGrant.toString()+" ON TABLE "+table4Grant.get(i) + " To Group " + this.user +";";
			}

			this.sql="";
			break;

		default:
			break;
		}
		
		if(typeQuery==EGiscTypeQuery.NEW)
		{
			return new GiscQueryFilter(sql, user, pass, db, driver, resultType, resultConcurency);
		}
		else if(typeQuery==EGiscTypeQuery.UPDATESQL)
		{
			return new GiscQueryFilter(sql);
		}
		else{return null;}
	}
	public GiscQueryFilterBuilder UserName(String userName)
	{
		this.user=userName;
		return this;
	}
	public GiscQueryFilterBuilder Pass(String password)
	{
		this.pass=password;
		return this;
	}
	public GiscQueryFilterBuilder Db(String database)
	{
		this.db=database;
		return this;
	}
	public GiscQueryFilterBuilder Sql(String sqlStatement)
	{
		this.sql=sqlStatement;
		return this;
	}
	public GiscQueryFilterBuilder Driver(String driver)
	{
		this.driver = driver;
		return this;
	}
	public GiscQueryFilterBuilder ResultType(int type)
	{
		this.resultType=type;
		return this;
	}
	public GiscQueryFilterBuilder ResultConcurency(int concur)
	{
		this.resultConcurency=concur;
		return this;
	}
	public GiscQueryFilterBuilder Table(String tab)
	{
		this.table=tab;
		return this;
	}
	public GiscQueryFilterBuilder Mode(EGiscModeQuery modeQuery)
	{
		this.mode=modeQuery;
		return this;
	}
	public GiscQueryFilterBuilder Type(EGiscTypeQuery typeQuery)
	{
		this.typeQuery=typeQuery;
		return this;
	}
	public GiscQueryFilterBuilder Grant(EGiscGrant grant)
	{
		this.typeGrant = grant;
		return this;
	}
	public GiscQueryFilterBuilder Table4Grant(String tableToGrant)
	{
		this.table4Grant.add(tableToGrant);
		return this;
	}
	/**
	 * Dùng cho câu lệnh insert
	 * @author HT
	 * @param stt: chỉ để nhận biết thứ tự
	 * @param type
	 * @param value
	 * @return
	 */
	public GiscQueryFilterBuilder InsertValue(int stt,EGiscType type, Object value)
	{
		switch (type) {
		case STRING:
			values.add("'"+(String)value+"'");
			break;
		case NUMBER:
			values.add(value.toString());
			break;
		case BOOLEAN:
			values.add(value.toString());
			break;
		case NULL:
			values.add("Null");
			break;

		default:
			break;
		}
		return this;
	}

}
